package com.dxy.hms.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Component
public class JwtUtil {

    public static String author;// 作者
    public static String module;// 模块
    public static String site;// 站点
    public static String issuer;// 签发人
    public static String secret;// 密钥
    public static long expire;// 失效时间，单位分钟
    public static boolean useCookie;// 是否使用cookie会话机制存放token

    @Value("${jwt.conf.author:dxy}")
    public void setAuthor(String author) {
        JwtUtil.author = author;
    }

    @Value("${jwt.conf.module:hms}")
    public void setModule(String module) {
        JwtUtil.module = module;
    }

    @Value("${jwt.conf.site:dxy.com}")
    public void setSite(String site) {
        JwtUtil.site = site;
    }

    @Value("${jwt.conf.issuer:dxy}")
    public void setIssuer(String issuer) {
        JwtUtil.issuer = issuer;
    }

    @Value("${jwt.conf.secret:fjioahgajgi}")
    public void setSecret(String secret) {
        JwtUtil.secret = secret;
    }

    @Value("${jwt.conf.expire:120}")
    public void setExpire(int expire) {
        JwtUtil.expire = expire;
    }

    @Value("${jwt.conf.useCookie:false}")
    public void setUseCookie(boolean useCookie) {
        JwtUtil.useCookie = useCookie;
    }

    private static final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;//签名算法

    public static SecretKey generateKey() {
        byte[] encodeKey = Base64.decodeBase64(Base64.encodeBase64(secret.getBytes()));
        return new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");// 获取加密key
    }


    public static String createToken(String userId) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 60 * 1000);
        Map<String, Object> header = new HashMap<>();
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        Map<String, Object> claims = new HashMap<>();
        claims.put("module", module);
        claims.put("author", author);
        JwtBuilder jwtBuilder = Jwts.builder()
                .setHeader(header)//保存头信息
                .setClaims(claims)//保存附加数据
                .setId(UUID.randomUUID().toString().replace("-", ""))
                .setIssuedAt(nowDate)//签发时间
                .setIssuer(issuer)//设置签发者
                .setSubject(userId)//此处可以设置要传递的数据userid
                .signWith(signatureAlgorithm, generateKey())//设置签名算法
                .setExpiration(expireDate);//配置失效时间
        return jwtBuilder.compact();
    }

    public static Jws<Claims> parseToken(String token) {
        return Jwts.parser().setSigningKey(generateKey()).parseClaimsJws(token);
    }

    public static boolean verifyToken(String token) {
        Jws<Claims> jws = parseToken(token);
        return jws != null;//没有异常就返回true
    }

    public static String refreshToken(String token) {
        return createToken(getUserId(token));
    }


    public static String getUserId(String token) {
        Jws<Claims> jws = parseToken(token);
        return jws.getBody().getSubject();
    }

    public static String getId(String token) {
        Jws<Claims> jws = parseToken(token);
        return jws.getBody().getId();
    }

    public static void main(String[] args) {
        JwtUtil.author = "dxy";
        JwtUtil.module = "hms";
        JwtUtil.site = "dxy.com";
        JwtUtil.issuer = "dxy";
        JwtUtil.secret = "fjioahgajgi";
        JwtUtil.expire = 120;
        String token = JwtUtil.createToken("123456");
        // String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJhdXRob3IiOiJkeHkiLCJtb2R1bGUiOiJobXMiLCJpc3MiOiJkeHkiLCJleHAiOjE3MjcxODg3NjYsImlhdCI6MTcyNzE4ODcwNiwianRpIjoiMjAwOWM1YzZlMGY4NDhmM2JmOGZlZjMwZmE1YjBiZDMifQ.k1Va6zLwyCwEfbdPiUNSZs3cOMXAdKZuudbOKat1jbw";
        System.out.println("token: " + token);
        System.out.println("verify: " + JwtUtil.verifyToken(token));
        System.out.println("userId: " + JwtUtil.getUserId(token));
        System.out.println("jti: " + JwtUtil.getId(token));
    }

}
